<html>
<head><meta http-equiv="Content-Type" content="text/html; charset=GBK">
<title>Lab #5: C Code Generation</title>
<link rel="stylesheet" type="text/css">
</head>

<body>
<font face="Trebuchet MS">
<table width="100%">
<tbody>
  <tr>
<td>
<h1>Lab #5: C Code Generation</h1>
<hr>

<h3>Introduction</h3>

<p>This lab requires you to write a generator program, which 
generates C code from AST2. Here C is ASCII C, the differences 
between C and AST2 are listed below.</p>
<ol>
<li>The biggest differences is that C has struct instead of class.</li>
<li>The member of struct in C shouldn't be a function, 
but it can be a funcion pointer.</li>
<li>Expressions, such as <code>new id()</code> and <code>new id[exp]</code>, don't exist in C.</li>
<li>...</li>
</ol>
<h3>Start</h3>

<p>
To start, you should download this 
<a href="http://staff.ustc.edu.cn/~bjhua/courses/compiler/2011/labs/lab5/lab5.rar">
package</a>,  
in which we have offered you a code skeleton. Here is a brief 
discription of the files:
</p>
<table valign="top" border="1" >
<tr>
    <td>parser/java.grm  </td>
    <td>
	the ML-Yacc specification file, <code>java.grm.sml</code> 
	is generated by the file.
	</td>
  </tr>
  <tr>
    <td><p>parser/parse.fun</p>
    <p>parser/parse.sig</p> </td>
    <td>the definition of Parse functor, it defines a function 
	<code>parse()</code>, which reads the input file and then 
	calls the lexer and parser</td>
  </tr>
  <tr>
    <td >libs/errormsg.sig, .sml</td>
    <td >the definition of error handling facilities, 
    they will be used in the lexer (and later labs)</td>
  </tr>
  <tr>
    <td >ast/ast.fun, .sig</td>
    <td >the definition of AST</td>
  </tr>
  <tr>
    <td >java2c/ast2.fun, .sig</td>
    <td >the definition of AST2</td>
  </tr>
  <tr>
    <td >c/CAst.fun, .sig</td>
    <td >the definition of CAst, in this lab, you need to translate AST2 to CAst</td>
  </tr>
  <tr>
    <td >java2c/genAST2.fun, .sig</td>
    <td >the definition of functor which translates AST to AST2</td>
  </tr>
  <tr>
    <td >java2c/genC.fun, .sig</td>
    <td >the definition of functor which translates AST2 to CAst</td>
  </tr>
  <tr>
    <td>main/main.sig, .sml</td>
    <td>the definition of Main structure, it defines a function
	<code>main()</code>, which will call function 
	<code>parse()</code> defined in <code>parser/parse.fun</code>,
	and another function <code>mainWrap()</code> wraps function 
	<code>main()</code></td>
  </tr>
  <tr>
    <td>call-main.sml </td>
    <td>the entry of whole program</td>
  </tr>
  <tr>
    <td>test\*.java </td>
    <td>these are seven input files to test your generator</td>
  </tr>
    <tr>
    <td>test\example\*.* </td>
    <td>this directory contains a sample code, <code>getSet_extends.java</code> is a source code of minijava, <code>getSet_extends.c</code> is the c code generated from <code>getSet_extends.java</code></td>
  </tr>
  <tr>
    <td>test\result.txt </td>
    <td>this file contains the running result of the seven test files</td>
  </tr>
</table>

<p>Considering difference between AST2 and C, we need to do the 
following things to accomplish the translating task.</p>
<ol>
<li>Translate <code>new id()</code> and <code>new id[exp]</code> to C code.</li>
<p>you can use <code>malloc</code> and <code>sizeof </code>instruction to represent <code>new id()</code> and <code>new id[exp]</code>, for example,</p>
<p><code>new A()</code> can be translated into the following code:</p>
<pre>
	A junk_0; //junk_0 is a temp variable
	junk_0 = malloc(sizeof(struct A));
</pre>
then the value of the expression <code>new A()</code> is <code>junk_0</code>.
<p><code>new int[exp]</code> can be translated into the following code:</p>
<pre>
	int junk_0;
	int * junk_1;
	junk_0 = exp;
	junk_1 = malloc(4*junk_0);</pre>
then the value of the expression <code>new int[exp]</code> is <code>junk_1</code>.
<p></p>
<li>Translate <code>class</code> to <code>struct</code>.</li>
<p><b>First</b>, members of struct shouldn't be functions. So you need to 
lift functions out of class, and then add some pointers, 
every pointer points to a lifted function.</p>
<p><b>Second</b>, every function should have a <code>this</code> pointer to be its argument, type of the <code>this</code> is a pointer to the class which the function lives in, and every class field used in function should be add a prefix <code>this-></code>.</p>
<p>For example, if we have following code:
<pre>
class A{
	int a;
	public int set(int a){
		this.a = a;
		return 0;
	}
	public int get(){
		return a;
	}
}

class B extends A{
	
}</pre>
<p>after translation, it may be</p>
<pre>
    struct Vtable_A{
        int (* display)();
        int (* get)();
        int (* set)();
    };
    
    struct Vtable_B{
        int (* display)();
        int (* get)();
        int (* set)();
    };
    
    struct Data_A{
        struct Vtable_A * vptr;
        int a;
    };
    
    struct Data_B{
        struct Vtable_B * vptr;
        int a;
    };
    
    struct Vtable_A obj_Vtable_A;
    struct Vtable_B obj_Vtable_B;
    
    int A_display (struct Data_A * this) {
        printf ("%d\n", this->a);
        return (0);
    }
    
    int A_get (struct Data_A * this) {
        return (this->a);
    }
    
    int A_set (struct Data_A * this, int a) {
        this->a = a;
        return (0);
    }
    
    int initVtables () {
        obj_Vtable_A.display = &amp;A_display;
        obj_Vtable_A.get = &amp;A_get;
        obj_Vtable_A.set = &amp;A_set;
        obj_Vtable_B.display = &amp;A_display;
        obj_Vtable_B.get = &amp;A_get;
        obj_Vtable_B.set = &amp;A_set;
    }</pre>
<p>Here, Every class is mapped into two structs, one called "data struct" stores fields of original class, the other called "function struct" stores function pointers, which point to functions of original class, and "data struct" must have a <code>vptr</code> pointer pointing to corresponding "function struct". Every "function struct" should have a global object, function pointer of which should be initialized by corresponding function, the global object should be assigned to <code>vptr</code> pointer of corresponding "data struct".</p>
<p>It's welcome to use your own method.</p>
</ol>

<h3>Your Job</h3>
<ol>
<li>You need to read <code>CAst.fun</code> and <code>genASTC.fun</code>, and <code>genASTC.fun</code> is the file you should modify.</li>
<li>The code you should modify looks like
<pre>	raise AddYourCodeHere</pre>
  So you should find all places marked as this and replace 
  them with your code.</li>
</ol>

<h3>Compile, run, and test</h3>
<ul>
<li><b>Compile the whole program.</b>  After you finish the code, 
run <code>cmd</code>, change the directory to lab5, 
and then run <code>build</code> to build the whole program.</li>
<li><b>Run the whole program.</b> 
Without changing the directory, type
<pre>jc .\test\arraySort.java</pre>It will output a <code>.c</code> files, then you can use a c compiler like<code> gcc</code> to compile and run it. The running output is list in <code>result.txt.</code> And you also need to test other six test files.</li>
</ul>

<p>
As always, a single test is far from complete. You will want to write 
your own test cases and 
thoroughly test your parser. Repeat the above procedure once 
you modify your code.
</p>

<h3>Handin</h3>
This completes the lab. Hand in your solution to information 
system.

</td>
</tr>
  
</tbody>
</table>
</font>


</body>
</html>
